﻿// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#pragma warning disable SA1202 // Elements should be ordered by access - because field initializer depend on each other

internal static class MyReferenceAssemblies
{
    internal static readonly string NuGetConfigPath = FindNuGetConfigPath();

    private static readonly ImmutableArray<PackageIdentity> AdditionalModernPackages = [
        ExtraPackages.Unsafe,
        ExtraPackages.Memory,
        ExtraPackages.Registry,
    ];

    private static readonly ImmutableArray<PackageIdentity> AdditionalLegacyPackagesNetFX = [
        new PackageIdentity("Microsoft.Windows.SDK.Contracts", "10.0.22621.2428"),
    ];

    private static readonly ImmutableArray<PackageIdentity> AdditionalLegacyPackagesNET = [
        new PackageIdentity("Microsoft.Windows.SDK.NET.Ref", "10.0.26100.57"),
    ];

    internal static readonly ReferenceAssemblies NetStandard20 = ReferenceAssemblies.NetStandard.NetStandard20
        .WithNuGetConfigFilePath(NuGetConfigPath)
        .AddPackages([.. AdditionalLegacyPackagesNetFX, .. AdditionalModernPackages]);

    private static string FindNuGetConfigPath()
    {
        string? path = AppContext.BaseDirectory;
        while (path is not null)
        {
            string candidate = Path.Combine(path, "nuget.config");
            if (File.Exists(candidate))
            {
                return candidate;
            }

            path = Path.GetDirectoryName(path);
        }

        throw new InvalidOperationException("Could not find NuGet.config by searching up from " + AppContext.BaseDirectory);
    }

    internal static class NetFramework
    {
        internal static readonly ReferenceAssemblies Net35 = ReferenceAssemblies.NetFramework.Net35.WindowsForms
            .WithNuGetConfigFilePath(NuGetConfigPath)
            .AddPackages(AdditionalLegacyPackagesNetFX);

        internal static readonly ReferenceAssemblies Net472 = ReferenceAssemblies.NetFramework.Net472.WindowsForms
            .WithNuGetConfigFilePath(NuGetConfigPath)
            .AddPackages([.. AdditionalLegacyPackagesNetFX, .. AdditionalModernPackages]);
    }

    internal static class Net
    {
        private static readonly Lazy<ReferenceAssemblies> LazyNet100 = new(() =>
            new(
                targetFramework: "net10.0",
                referenceAssemblyPackage: new PackageIdentity("Microsoft.NETCore.App.Ref", "10.0.0"),
                referenceAssemblyPath: Path.Combine("ref", "net10.0")));

        internal static readonly ReferenceAssemblies Net80 = ReferenceAssemblies.Net.Net80
            .WithNuGetConfigFilePath(NuGetConfigPath)
            .AddPackages([.. AdditionalLegacyPackagesNET, .. AdditionalModernPackages]);

        internal static readonly ReferenceAssemblies Net90 = ReferenceAssemblies.Net.Net90
            .WithNuGetConfigFilePath(NuGetConfigPath)
            .AddPackages([.. AdditionalLegacyPackagesNET, .. AdditionalModernPackages]);

        internal static ReferenceAssemblies Net100 => LazyNet100.Value
              .WithNuGetConfigFilePath(NuGetConfigPath)
              .AddPackages([.. AdditionalLegacyPackagesNET, .. AdditionalModernPackages]);
    }

    internal static class ExtraPackages
    {
        internal static readonly PackageIdentity Unsafe = new PackageIdentity("System.Runtime.CompilerServices.Unsafe", "6.0.0");
        internal static readonly PackageIdentity Memory = new PackageIdentity("System.Memory", "4.5.5");
        internal static readonly PackageIdentity Registry = new PackageIdentity("Microsoft.Win32.Registry", "5.0.0");
    }
}
